<template>
  <el-dialog
    v-model="dialogVisible"
    :title="title"
    :width="width"
    :before-close="handleClose"
    @closed="handleClosed"
  >
    <el-form
      ref="formRef"
      :model="formData"
      :rules="rules"
      label-width="100px"
      :validate-on-rule-change="false"
    >
      <slot></slot>
    </el-form>
    
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="handleCancel">{{ cancelText }}</el-button>
        <el-button type="primary" @click="handleSubmit" :loading="loading">
          {{ confirmText }}
        </el-button>
      </span>
    </template>
  </el-dialog>
</template>

<script setup>
import { ref, computed, watch } from 'vue'

/**
 * 组件属性定义
 */
const props = defineProps({
  // 对话框是否可见
  modelValue: {
    type: Boolean,
    default: false
  },
  // 对话框标题
  title: {
    type: String,
    default: '表单'
  },
  // 对话框宽度
  width: {
    type: String,
    default: '500px'
  },
  // 表单数据
  data: {
    type: Object,
    default: () => ({})
  },
  // 表单校验规则
  rules: {
    type: Object,
    default: () => ({})
  },
  // 确认按钮文本
  confirmText: {
    type: String,
    default: '确定'
  },
  // 取消按钮文本
  cancelText: {
    type: String,
    default: '取消'
  },
  // 加载状态
  loading: {
    type: Boolean,
    default: false
  }
})

/**
 * 组件事件定义
 */
const emit = defineEmits([
  'update:modelValue',
  'submit',
  'cancel',
  'close',
  'update:data'
])

// 表单引用
const formRef = ref(null)

// 对话框可见状态
const dialogVisible = computed({
  get: () => props.modelValue,
  set: (val) => emit('update:modelValue', val)
})

// 表单数据
const formData = ref({...props.data})

// 监听外部数据变化
watch(() => props.data, (val) => {
  formData.value = {...val}
}, { deep: true })

// 监听对话框打开状态
watch(() => props.modelValue, (val) => {
  if (val) {
    // 对话框打开时，重置表单数据
    formData.value = {...props.data}
  }
})

/**
 * 处理表单提交
 */
const handleSubmit = () => {
  formRef.value?.validate((valid) => {
    if (valid) {
      emit('submit', formData.value)
    }
  })
}

/**
 * 处理取消操作
 */
const handleCancel = () => {
  emit('cancel')
  dialogVisible.value = false
}

/**
 * 处理关闭操作
 */
const handleClose = (done) => {
  emit('close')
  done()
}

/**
 * 处理对话框关闭后的操作
 */
const handleClosed = () => {
  formRef.value?.resetFields()
}

/**
 * 重置表单
 */
const resetForm = () => {
  formRef.value?.resetFields()
}

/**
 * 暴露组件方法
 */
defineExpose({
  resetForm,
  validate: (callback) => formRef.value?.validate(callback)
})
</script>

<style lang="scss" scoped>
.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}
</style> 